import os
import re
import shutil

INT32_TYPE = "int32"
INT64_TYPE = "int64"
STR_TYPE = "string"
BOOL_TYPE = "bool"
FLOAT_TYPE = "float"

repeated_desc = "repeated"

globalCount = 0

LINE_INDEX_W = 0
LINE_INDEX_R = 0


def readRepeatReal(fileObj, pName, dataName, index, rmsg=None):
    content = '''
    int #pName#_n = pbc_rmessage_size(pbc_rmsg, "#pName#");
    Json::Value #pName#Arr;
    for(int #pName#_i=0;#pName#_i<#pName#_n;++#pName#_i)
    {
    double #pName#_v = pbc_rmessage_real(pbc_rmsg, "#pName#", #pName#_i);
    #pName#Arr.append(#pName#_v);
    }
    #dataName#["#pName#"] = #pName#Arr;\n
    '''
    if rmsg != None:
        content = content.replace("pbc_rmsg", rmsg)
    content = content.replace("#pName#", pName)
    content = content.replace("#dataName#", dataName)
    fileObj.write(content)


def readRepeatInt64(fileObj, pName, dataName, index, rmsg=None):
    content = '''
    int #pName#_n = pbc_rmessage_size(pbc_rmsg, "#pName#");
    Json::Value #pName#Arr;
    for(int #pName#_i=0;#pName#_i<#pName#_n;++#pName#_i)
    {
    uint32_t hi,low;
    uint32_t low = pbc_rmessage_integer(pbc_rmsg, "#pName#",  #pName#_i, &hi);
    uint64_t #pName#_v = (int64_t)((uint64_t)hi << 32 | (uint64_t)low);
    #pName#Arr.append(#pName#_v);
    }
    #dataName#["#pName#"] = #pName#Arr;\n
    '''
    if rmsg != None:
        content = content.replace("pbc_rmsg", rmsg)
    content = content.replace("#pName#", pName)
    content = content.replace("#dataName#", dataName)
    fileObj.write(content)
    pass


def readRepeatInt(fileObj, pName, dataName, index, rmsg=None):
    content = '''
    int #pName#_n = pbc_rmessage_size(pbc_rmsg, "#pName#");
    Json::Value #pName#Arr;
    for(int #pName#_i=0;#pName#_i<#pName#_n;++#pName#_i)
    {
    int #pName#_v = pbc_rmessage_integer(pbc_rmsg, "#pName#", #pName#_i, NULL);
    #pName#Arr.append(#pName#_v);
    }
    #dataName#["#pName#"] = #pName#Arr;\n
    '''
    if rmsg != None:
        content = content.replace("pbc_rmsg", rmsg)
    content = content.replace("#pName#", pName)
    content = content.replace("#dataName#", dataName)
    fileObj.write(content)


def readRepeatString(fileObj, pName, dataName, index, rmsg=None):
    content = '''
    int #pName#_n = pbc_rmessage_size(pbc_rmsg, "#pName#");
    Json::Value #pName#Arr;
    for(int #pName#_i=0;#pName#_i<#pName#_n;++#pName#_i)
    {
    std::string #pName#_v = pbc_rmessage_string(pbc_rmsg, "#pName#", #pName#_i, NULL);
    #pName#Arr.append(#pName#_v);
    }
    #dataName#["#pName#"] = #pName#Arr;\n
    '''
    if rmsg != None:
        content = content.replace("pbc_rmsg", rmsg)
    content = content.replace("#pName#", pName)
    content = content.replace("#dataName#", dataName)
    fileObj.write(content)


def readRepeatStruct(fileObj, pName, otherMap, pType, dataName, index, rmsg=None):
    if otherMap.get(pType) != None:
        content = '''
        {
        int #pName#_n = pbc_rmessage_size(pbc_rmsg, "#pName#");
        for(int #pName#_i=0;#pName#_i<#pName#_n;++#pName#_i)
        {
        struct pbc_rmessage* #pName# = pbc_rmessage_message(pbc_rmsg, "#pName#", #pName#_i);\n
        #dataName#["#pName#"] = Json::Value();
        Json::Value arrValue;
        '''
        if rmsg != None:
            content = content.replace("pbc_rmsg", rmsg)
        content = content.replace("#pName#", pName)
        content = content.replace("#dataName#", dataName)
        fileObj.write(content)

        params = otherMap[pType]
        params = params.split(";")
        for param in params:
            values = param.split("=")
            value = values[0].strip()
            pbParams = value.split(" ")
            count = len(pbParams)
            if count == 2:
                pName1 = pbParams[count - 1]
                pType1 = pbParams[count - 2]
                dataName1 = "arrValue"
                if pType1 == INT32_TYPE:
                    readSignalInt(fileObj, pName1, dataName1, pName + "_i", pName)
                elif pType1 == INT64_TYPE:
                    readSignalInt64(fileObj, pName1, dataName1, pName + "_i", pName)
                elif pType1 == STR_TYPE:
                    readSignalString(fileObj, pName1, dataName1, pName + "_i", pName)
                elif pType1 == FLOAT_TYPE:
                    readSignalReal(fileObj, pName1, dataName1, pName + "_i", pName)
                else:
                    readSignalStruct(fileObj, pName1, dataName1, pName + "_i", pName)
            elif count >= 3:
                pName1 = pbParams[count - 1]
                pType1 = pbParams[count - 2]
                pDesc1 = pbParams[count - 3]
                dataName1 = "arrValue"
                if pType1 == INT32_TYPE:
                    if pDesc1 == repeated_desc:
                        readRepeatInt(fileObj, pName1, dataName1, pName + "_i", pName)
                    else:
                        readSignalInt(fileObj, pName1, dataName1, pName + "_i", pName)
                elif pType1 == INT64_TYPE:
                    if pDesc1 == repeated_desc:
                        readRepeatInt64(fileObj, pName1, dataName1, pName + "_i", pName)
                    else:
                        readSignalInt(fileObj, pName1, dataName1, pName + "_i", pName)
                elif pType1 == STR_TYPE:
                    if pDesc1 == repeated_desc:
                        readRepeatString(fileObj, pName1, dataName1, pName + "_i", pName)
                    else:
                        readSignalString(fileObj, pName1, dataName1, pName + "_i", pName)
                elif pType1 == FLOAT_TYPE:
                    if pDesc1 == repeated_desc:
                        readRepeatReal(fileObj, pName1, dataName1, pName + "_i", pName)
                    else:
                        readSignalReal(fileObj, pName1, dataName1, pName + "_i", pName)
                else:
                    if pDesc1 == repeated_desc:
                        readRepeatStruct(fileObj, pName1, otherMap, pType1, dataName1, pName + "_i", pName)
                    else:
                        readSignalStruct(fileObj, pName1, otherMap, pType1, dataName1, pName + "_i", pName)

        fileObj.write(
            "#dataName#[\"#pName#\"].append(arrValue);".replace("#dataName#", dataName).replace("#pName#", pName))
        fileObj.write("}\n}\n")


def readSignalReal(fileObj, pName, dataName, index, rmsg=None):
    content = '''
    double #pName# = pbc_rmessage_real(pbc_rmsg, "#pName#", #index#);
    #dataName#["#pName#"]= #pName#;\n
    '''
    if rmsg != None:
        content = content.replace("pbc_rmsg", rmsg)
    content = content.replace("#pName#", pName)
    content = content.replace("#index#", str(index))
    content = content.replace("#dataName#", dataName)
    fileObj.write(content)


def readSignalInt64(fileObj, pName, dataName, index, rmsg=None):
    content = '''
    {
    uint32_t hi,low;
    uint32_t low = pbc_rmessage_integer(pbc_rmsg, "time", 0, &hi);
    int64_t #pName# = (int64_t)((uint64_t)hi << 32 | (uint64_t)low);
    #dataName#["#pName#"]= #pName#;\n
    }
    '''
    if rmsg != None:
        content = content.replace("pbc_rmsg", rmsg)
    content = content.replace("#pName#", pName)
    content = content.replace("#index#", str(index))
    content = content.replace("#dataName#", dataName)
    fileObj.write(content)
    pass


def readSignalInt(fileObj, pName, dataName, index, rmsg=None):
    content = '''
    int #pName# = pbc_rmessage_integer(pbc_rmsg, "#pName#", #index#, NULL);
    #dataName#["#pName#"]= #pName#;\n
    '''
    if rmsg != None:
        content = content.replace("pbc_rmsg", rmsg)
    content = content.replace("#pName#", pName)
    content = content.replace("#index#", str(index))
    content = content.replace("#dataName#", dataName)
    fileObj.write(content)


def readSignalString(fileObj, pName, dataName, index, rmsg=None):
    content = '''
    std::string #pName# = pbc_rmessage_string(pbc_rmsg, "#pName#", #index#, NULL);
    #dataName#["#pName#"]= #pName#;\n
    '''
    if rmsg != None:
        content = content.replace("pbc_rmsg", rmsg)
    content = content.replace("#pName#", pName)
    content = content.replace("#index#", str(index))
    content = content.replace("#dataName#", dataName)
    fileObj.write(content)


def readSignalStruct(fileObj, pName, otherMap, pType, dataName, index, rmsg=None):
    if otherMap.get(pType) != None:
        content = '''
        {
        struct pbc_rmessage* #pName# = pbc_rmessage_message(pbc_rmsg, "#pName#", 0);
        (*out)["#pName#"]= Json::Value();
        '''
        if rmsg != None:
            content = content.replace("pbc_rmsg", rmsg)
        content = content.replace("#pName#", pName)
        fileObj.write(content)

        params = otherMap[pType]
        params = params.split(";")
        for param in params:
            values = param.split("=")
            value = values[0].strip()
            pbParams = value.split(" ")
            count = len(pbParams)
            if count == 2:
                pName1 = pbParams[count - 1]
                pType1 = pbParams[count - 2]
                dataName1 = dataName + "[\"" + pName + "\"]"
                if pType1 == INT32_TYPE:
                    readSignalInt(fileObj, pName1, dataName1, 0, pName)
                elif pType1 == INT64_TYPE:
                    readSignalInt64(fileObj, pName1, dataName1, 0, pName)
                elif pType1 == STR_TYPE:
                    readSignalString(fileObj, pName1, dataName1, 0, pName)
                elif pType1 == FLOAT_TYPE:
                    readSignalReal(fileObj, pName1, dataName1, 0, pName)
                else:
                    readSignalStruct(fileObj, pName1, otherMap, pType1, dataName1, 0, pName)
            elif count >= 3:
                pName1 = pbParams[count - 1]
                pType1 = pbParams[count - 2]
                pDesc1 = pbParams[count - 3]
                dataName1 = dataName + "[\"" + pName + "\"]"
                if pType1 == INT32_TYPE:
                    if pDesc1 == repeated_desc:
                        readRepeatInt(fileObj, pName1, dataName1, 0, pName)
                    else:
                        readSignalInt(fileObj, pName1, dataName1, 0, pName)
                elif pType1 == INT64_TYPE:
                    if pDesc1 == repeated_desc:
                        readRepeatInt64(fileObj, pName1, dataName1, 0, pName)
                    else:
                        readSignalInt(fileObj, pName1, dataName1, 0, pName)
                elif pType1 == STR_TYPE:
                    if pDesc1 == repeated_desc:
                        readRepeatString(fileObj, pName1, dataName1, 0, pName)
                    else:
                        readSignalString(fileObj, pName1, dataName1, 0, pName)
                elif pType1 == FLOAT_TYPE:
                    if pDesc1 == repeated_desc:
                        readRepeatReal(fileObj, pName1, dataName1, 0, pName)
                    else:
                        readSignalReal(fileObj, pName1, dataName1, 0, pName)
                else:
                    if pDesc1 == repeated_desc:
                        readRepeatStruct(fileObj, pName1, otherMap, pType1, dataName1, 0, pName)
                    else:
                        readSignalStruct(fileObj, pName1, otherMap, pType1, dataName1, 0, pName)

        fileObj.write("}\n")


def genPbcC2SFunc(c2sMap, otherMap):
    fileObj = open("../GameServer/GameServer/DecodeMessageBuffer.cpp", "w")
    listRegister = []
    fileObj.write('''#include"DecodeMessageBuffer.h"
#include"pbc/pbc.h"
#include"MessageConst.h"
#include<iostream>
#include<string>

DecodeMessageBuffer::DecodeMessageBuffer()
{
	initDecodeFunc();
}

DecodeMessageBuffer::~DecodeMessageBuffer()
{
	m_decodeFuncMaps.clear();
}

void DecodeMessageBuffer::decode(char* buff, int len, pbc_env* env, Json::Value* out)
{
	short id;
	memcpy(&id, buff, sizeof(id));
	auto iter = m_decodeFuncMaps.find(id);
	(*out)["messageid"] = id;
	if (iter != m_decodeFuncMaps.end())
	{
		(this->*(iter->second))(buff + 2, len - sizeof(id), env, out);
	}
}

void DecodeMessageBuffer::registerDecodeFunc(int id, DecodeFunc func)
{
	m_decodeFuncMaps[id] = func;
}
\n''')
    LINE_INDEX_R = 0
    for key in c2sMap.keys():
        listRegister.append("decode" + key)
        content = c2sMap[key]
        params = content.split(";")
        head = '''
        void DecodeMessageBuffer::decode#key#(char* buff, int len, pbc_env* env, Json::Value* out)
        {
        pbc_slice slice;
        slice.len = len;
        slice.buffer = malloc(slice.len);
        memcpy(slice.buffer, buff, len);
        pbc_rmessage* pbc_rmsg = pbc_rmessage_new(env, "tutorial.#key#", &slice);\n
        '''
        head = head.replace("#key#", key)
        fileObj.write(head)
        for param in params:
            values = param.split("=")
            value = values[0].strip()
            pbParams = value.split(" ")
            count = len(pbParams)
            if count == 2:
                pName = pbParams[count - 1]
                pType = pbParams[count - 2]
                print(pName + " " + pType)
                if pType == INT32_TYPE:
                    readSignalInt(fileObj, pName, "(*out)", 0)
                elif pType == INT64_TYPE:
                    readSignalInt64(fileObj, pName, "(*out)", 0)
                elif pType == STR_TYPE:
                    readSignalString(fileObj, pName, "(*out)", 0)
                elif pType == FLOAT_TYPE:
                    readSignalReal(fileObj, pName, "(*out)", 0)
                else:
                    readSignalStruct(fileObj, pName, otherMap, pType, "(*out)", 0)
            elif count >= 3:
                pName = pbParams[count - 1]
                pType = pbParams[count - 2]
                pDesc = pbParams[count - 3]
                if pType == INT32_TYPE:
                    if pDesc == repeated_desc:
                        readRepeatInt(fileObj, pName, "(*out)", 0)
                    else:
                        readSignalInt(fileObj, pName, "(*out)", 0)
                elif pType == INT64_TYPE:
                    if pDesc == repeated_desc:
                        readRepeatInt64(fileObj, pName, "(*out)", 0)
                    else:
                        readSignalInt(fileObj, pName, "(*out)", 0)
                elif pType == STR_TYPE:
                    if pDesc == repeated_desc:
                        readRepeatString(fileObj, pName, "(*out)", 0)
                    else:
                        readSignalString(fileObj, pName, "(*out)", 0)
                elif pType == FLOAT_TYPE:
                    if pDesc == repeated_desc:
                        readRepeatReal(fileObj, pName, "(*out)", 0)
                    else:
                        readSignalReal(fileObj, pName, "(*out)", 0)
                else:
                    if pDesc == repeated_desc:
                        readRepeatStruct(fileObj, pName, otherMap, pType, "(*out)", 0)
                    else:
                        readSignalStruct(fileObj, pName, otherMap, pType, "(*out)", 0)

        fileObj.write('''
        pbc_rmessage_delete(pbc_rmsg);
        free(slice.buffer);\n''')
        fileObj.write("}\n")

    registerContent = '''
    void DecodeMessageBuffer::initDecodeFunc()
    {
    '''
    for funcName in listRegister:
        regisFunc = "registerDecodeFunc(#IdFunc#, &DecodeMessageBuffer::#funcName#);\n"
        idFunc = funcName.replace("decode", "")
        idFunc = "ID_" + idFunc
        regisFunc = regisFunc.replace("#IdFunc#", idFunc)
        regisFunc = regisFunc.replace("#funcName#", funcName)
        registerContent = registerContent + regisFunc
    registerContent = registerContent + "\n}"
    fileObj.write(registerContent)
    fileObj.close()


def writeRepeatReal(fileObj, pName, dataName, wmsg=None):
    content = '''
    int count=data[\"#pName#\"].size();
    for(int #pName#_i=0;#pName#_i<count;++#pName#_i)
    {
    pbc_wmessage_real(encodeBuff.wmsg, \"#pName#\", #dataName#[\"#pName#\"][#pName#_i].asDouble());
    }\n'''
    if wmsg != None:
        content = content.replace("encodeBuff.wmsg", wmsg)
    content.replace("#dataName#", dataName)
    content = content.replace("#pName#", pName)
    fileObj.write(content)


def writeRepeatInt64(fileObj, pName, dataName, wmsg=None):
    content = '''
    int count=data[\"#pName#\"].size();
    for(int #pName#_i=0;#pName#_i<count;++#pName#_i)
    {
    int64_t tempVar = #dataName#[\"#pName#\"][#pName#_i].asInt64();
    int32_t hi = (uint32_t)(temVar >> 32);
    pbc_wmessage_integer(encodeBuff.wmsg, \"#pName#\",(int32_t)tempVar, hi);
    }\n'''
    if wmsg != None:
        content = content.replace("encodeBuff.wmsg", wmsg)
    content.replace("#dataName#", dataName)
    content = content.replace("#pName#", pName)
    fileObj.write(content)
    pass


def writeRepeatInt(fileObj, pName, dataName, wmsg=None):
    content = '''
    int count=data[\"#pName#\"].size();
    for(int #pName#_i=0;#pName#_i<count;++#pName#_i)
    {
    pbc_wmessage_integer(encodeBuff.wmsg, \"#pName#\", #dataName#[\"#pName#\"][#pName#_i].asInt(), 0);
    }\n'''
    if wmsg != None:
        content = content.replace("encodeBuff.wmsg", wmsg)
    content.replace("#dataName#", dataName)
    content = content.replace("#pName#", pName)
    fileObj.write(content)


def writeRepeatString(fileObj, pName, dataName, wmsg=None):
    content = '''
    int count=data[\"#pName#\"].size();
    for(int #pName#_i=0;#pName#_i<count;++#pName#_i)
    {
    pbc_wmessage_integer(encodeBuff.wmsg, \"#pName#\", #dataName#[\"#pName#\"][#pName#_i].asCString(), 0);
    }\n'''
    if wmsg != None:
        content = content.replace("encodeBuff.wmsg", wmsg)
    content = content.replace("#dataName#", dataName)
    content = content.replace("#pName#", pName)
    fileObj.write(content)


def writeRepeatStruct(fileObj, pName, otherMap, pType, dataName, wmsg=None):
    if otherMap.get(pType) != None:
        content = '''
         int count=data[\"#pName#\"].size();
         for(int #pName#_i=0;#pName#_i<count;++#pName#_i)
         {
         struct pbc_wmessage* #pName# = pbc_wmessage_message(encodeBuff.wmsg, \"#pName#\");
         '''
        if wmsg != None:
            content = content.replace("encodeBuff.wmsg", wmsg)
        content = content.replace("#pName#", pName)
        fileObj.write(content)
        params = otherMap[pType]
        params = params.split(";")
        for param in params:
            values = param.split("=")
            value = values[0]
            value = value.strip()
            pbParams = value.split(" ")
            count = len(pbParams)
            print(param)
            if count == 2:
                pName1 = pbParams[count - 1]
                pType1 = pbParams[count - 2]
                dataName1 = dataName + "[\"" + pName + "\"][" + pName + "_i]"
                if pType1 == INT32_TYPE:
                    writeSignalInt(fileObj, pName1, dataName1, pName)
                elif pType1 == INT64_TYPE:
                    writeSignalInt64(fileObj, pName1, dataName1, pName)
                elif pType1 == STR_TYPE:
                    writeSignalString(fileObj, pName1, dataName1, pName)
                elif pType1 == FLOAT_TYPE:
                    writeSignalReal(fileObj, pName1, dataName1, pName)
                else:
                    writeSignalStruct(fileObj, pName1, otherMap, pType1, pName)
            elif count >= 3:
                pName1 = pbParams[count - 1]
                pType1 = pbParams[count - 2]
                pDesc1 = pbParams[count - 3]
                dataName1 = dataName + "[\"" + pName + "\"][" + pName + "_i]"
                if pType1 == INT32_TYPE:
                    if pDesc1 == repeated_desc:
                        writeRepeatInt(fileObj, pName1, dataName1, pName)
                    else:
                        writeSignalInt(fileObj, pName1, dataName1, pName)
                elif pType1 == INT64_TYPE:
                    if pDesc1 == repeated_desc:
                        writeRepeatInt64(fileObj, pName1, dataName1, pName)
                    else:
                        writeSignalInt(fileObj, pName1, dataName1, pName)
                elif pType1 == STR_TYPE:
                    if pDesc1 == repeated_desc:
                        writeRepeatString(fileObj, pName1, dataName1, pName)
                    else:
                        writeSignalString(fileObj, pName1, dataName1, pName)
                elif pType1 == FLOAT_TYPE:
                    if pDesc1 == repeated_desc:
                        writeRepeatReal(fileObj, pName1, dataName1, pName)
                    else:
                        writeSignalReal(fileObj, pName1, dataName1, pName)
                else:
                    if pDesc1 == repeated_desc:
                        writeRepeatStruct(fileObj, pName1, otherMap, pType1, dataName1, pName)
                    else:
                        writeSignalStruct(fileObj, pName1, otherMap, pType1, dataName1, pName)

        fileObj.write("}\n")


def writeSignalReal(fileObj, pName, dataName, wmsg=None):
    content = "pbc_wmessage_real(encodeBuff.wmsg, \"#pName#\", #dataName#[\"#pName#\"].asDouble());\n"
    if wmsg != None:
        content = content.replace("encodeBuff.wmsg", wmsg)
    content = content.replace("#dataName#", dataName)
    content = content.replace("#pName#", pName)
    fileObj.write(content)


def writeSignalInt64(fileObj, pName, dataName, wmsg=None):
    content = '''
    {
    int64_t temVar =  #dataName#[\"#pName#\"].asInt64();
    int32_t hi = (uint32_t)(temVar >> 32);
    pbc_wmessage_integer(encodeBuff.wmsg, \"#pName#\",(int32_t)temVar, hi);\n
    }
    '''
    if wmsg != None:
        content = content.replace("encodeBuff.wmsg", wmsg)
    content = content.replace("#dataName#", dataName)
    content = content.replace("#pName#", pName)
    fileObj.write(content)
    pass


def writeSignalInt(fileObj, pName, dataName, wmsg=None):
    content = "pbc_wmessage_integer(encodeBuff.wmsg, \"#pName#\", #dataName#[\"#pName#\"].asInt(), 0);\n"
    if wmsg != None:
        content = content.replace("encodeBuff.wmsg", wmsg)
    content = content.replace("#dataName#", dataName)
    content = content.replace("#pName#", pName)
    fileObj.write(content)


def writeSignalString(fileObj, pName, dataName, wmsg=None):
    content = "pbc_wmessage_string(encodeBuff.wmsg, \"#pName#\", #dataName#[\"#pName#\"].asCString(), -1);\n"
    if wmsg != None:
        content = content.replace("encodeBuff.wmsg", wmsg)
    content = content.replace("#dataName#", dataName)
    content = content.replace("#pName#", pName)
    fileObj.write(content)


def writeSignalStruct(fileObj, pName, otherMap, pType, dataName, wmsg=None):
    if otherMap.get(pType) != None:
        content = "struct pbc_wmessage* #pName# = pbc_wmessage_message(encodeBuff.wmsg, \"#pName#\");\n"
        if wmsg != None:
            content = content.replace("encodeBuff.wmsg", wmsg)
        content = content.replace("#pName#", pName)
        params = otherMap[pType]
        params = params.split(";")
        fileObj.write(content)
        for param in params:
            values = param.split("=")
            value = values[0]
            value = value.strip()
            pbParams = value.split(" ")
            count = len(pbParams)
            if count == 2:
                pName1 = pbParams[count - 1]
                pType1 = pbParams[count - 2]
                dataName1 = dataName + "[\"" + pName + "\"]"
                if pType1 == INT32_TYPE:
                    writeSignalInt(fileObj, pName1, dataName1, pName)
                elif pType1 == INT64_TYPE:
                    writeSignalInt64(fileObj, pName1, dataName1, pName)
                elif pType1 == STR_TYPE:
                    writeSignalString(fileObj, pName1, dataName1, pName)
                elif pType1 == FLOAT_TYPE:
                    writeSignalReal(fileObj, pName1, dataName1, pName)
                else:
                    writeSignalStruct(fileObj, pName1, otherMap, pType1, dataName1, pName)
            elif count >= 3:
                pName1 = pbParams[count - 1]
                pType1 = pbParams[count - 2]
                pDesc1 = pbParams[count - 3]
                dataName1 = dataName + "[\"" + pName + "\"]"
                if pType1 == INT32_TYPE:
                    if pDesc1 == repeated_desc:
                        writeRepeatInt(fileObj, pName1, dataName1, pName)
                    else:
                        writeSignalInt(fileObj, pName1, dataName1, pName)
                elif pType1 == INT64_TYPE:
                    if pDesc1 == repeated_desc:
                        writeRepeatInt64(fileObj, pName1, dataName1, pName)
                    else:
                        writeSignalInt(fileObj, pName1, dataName1, pName)
                elif pType1 == STR_TYPE:
                    if pDesc1 == repeated_desc:
                        writeRepeatString(fileObj, pName1, dataName1, pName)
                    else:
                        writeSignalString(fileObj, pName1, dataName1, pName)
                elif pType == FLOAT_TYPE:
                    if pDesc1 == repeated_desc:
                        writeRepeatReal(fileObj, pName1, dataName1, pName)
                    else:
                        writeSignalReal(fileObj, pName1, dataName1, pName)
                else:
                    if pDesc1 == repeated_desc:
                        writeRepeatStruct(fileObj, pName1, otherMap, pType1, dataName1, pName)
                    else:
                        writeSignalStruct(fileObj, pName1, otherMap, pType1, dataName1, pName)


def genPbcS2CFunc(s2cMap, otherMap):
    fileObj = open("../GameServer/GameServer/EncodeMessageBuffer.cpp", "w")
    listRegister = []
    fileObj.write('''
#include "EncodeMessageBuffer.h"
#include"pbc/pbc.h"
#include"MessageIDConst.h"
#include<iostream>

EncodeMessageBuffer::EncodeMessageBuffer()
{
	initEncoder();
}

EncodeMessageBuffer::~EncodeMessageBuffer()
{
}

EncodeBuff EncodeMessageBuffer::encode(pbc_env* env, Json::Value& data)
{
	auto id = data["messageid"].asInt();
	auto iter = m_encodeMaps.find(id);
	if (iter != m_encodeMaps.end())
	{
		return (this->*(iter->second))(env, data);
	}
	return EncodeBuff();
}
    \n''')
    for key in s2cMap.keys():
        listRegister.append("encode" + key)
        content = s2cMap[key]
        params = content.split(";")
        head = '''
        EncodeBuff EncodeMessageBuffer::encode#name#(pbc_env* env, Json::Value& data)
        {
        EncodeBuff encodeBuff;
        encodeBuff.slice = new pbc_slice;
        encodeBuff.wmsg= pbc_wmessage_new(env, "tutorial.#name#");\n'''
        head = head.replace("#name#", key)
        fileObj.write(head)
        for param in params:
            values = param.split("=")
            value = values[0]
            value = value.strip()
            pbParams = value.split(" ")
            count = len(pbParams)
            if count == 2:
                pName = pbParams[count - 1]
                pType = pbParams[count - 2]
                if pType == INT32_TYPE:
                    writeSignalInt(fileObj, pName, "data")
                elif pType == INT64_TYPE:
                    writeSignalInt64(fileObj, pName, "data")
                elif pType == STR_TYPE:
                    writeSignalString(fileObj, pName, "data")
                elif pType == FLOAT_TYPE:
                    writeSignalReal(fileObj, pName, "data")
                else:
                    writeSignalStruct(fileObj, pName, otherMap, pType, "data")
            elif count >= 3:
                pName = pbParams[count - 1]
                pType = pbParams[count - 2]
                pDesc = pbParams[count - 3]
                if pType == INT32_TYPE:
                    if pDesc == repeated_desc:
                        writeRepeatInt(fileObj, pName, "data")
                    else:
                        writeSignalInt(fileObj, pName, "data")
                elif pType == INT64_TYPE:
                    if pDesc == repeated_desc:
                        writeRepeatInt64(fileObj, pName, "data")
                    else:
                        writeSignalInt(fileObj, pName, "data")
                elif pType == STR_TYPE:
                    if pDesc == repeated_desc:
                        writeRepeatString(fileObj, pName, "data")
                    else:
                        writeSignalString(fileObj, pName, "data")
                elif pType == FLOAT_TYPE:
                    if pDesc == repeated_desc:
                        writeRepeatReal(fileObj, pName, "data")
                    else:
                        writeSignalReal(fileObj, pName, "data")
                else:
                    if pDesc == repeated_desc:
                        writeRepeatStruct(fileObj, pName, otherMap, pType, "data")
                    else:
                        writeSignalStruct(fileObj, pName, otherMap, pType, "data")
        fileObj.write('''
        pbc_wmessage_buffer(encodeBuff.wmsg, encodeBuff.slice);
        return encodeBuff;\n''')
        fileObj.write("}\n")

    registerContent = '''
    void EncodeMessageBuffer::initEncoder()
    {
    '''
    for funcName in listRegister:
        regisFunc = "m_encodeMaps[#IdFunc#] = &EncodeMessageBuffer::#funcName#;\n"
        idFunc = funcName.replace("encode", "")
        idFunc = "ID_" + idFunc
        regisFunc = regisFunc.replace("#IdFunc#", idFunc)
        regisFunc = regisFunc.replace("#funcName#", funcName)
        registerContent = registerContent + regisFunc
    registerContent = registerContent + "}\n"
    fileObj.write(registerContent)
    fileObj.close()


def getPbcId():
    fileObj = open("mmorpg.proto", "r")
    c2sMap = {}
    s2cMap = {}
    otherMap = {}
    line = fileObj.readline()
    while (line):
        if re.search("message .* {", line):
            messageName = line.replace("message", "")
            messageName = messageName.replace("{", "")
            messageName = messageName.replace(" ", "")
            messageName = messageName.replace("\n", "")
            content = ""
            line = fileObj.readline()
            while (line):
                if re.search("}", line):
                    break
                content = content + line.replace("\n", "")
                line = fileObj.readline()
            if re.search("C2S_", messageName):
                c2sMap[messageName] = content
            elif re.search("S2C_", messageName):
                s2cMap[messageName] = content
            else:
                otherMap[messageName] = content
        line = fileObj.readline()

    fileObj.close()
    genPbcC2SFunc(c2sMap, otherMap)
    genPbcS2CFunc(s2cMap, otherMap)
    print(s2cMap)
    print(otherMap)


if (__name__ == "__main__"):
    arr = []
    getPbcId()
    os.system("pause")
    pass
